package prod_line

import (
	"bytes"
	"context"
	"errors"
	"github.com/lishimeng/app-starter/stream"
)

type CheckResult struct {
	Items []CheckItem
}

type CheckItem struct {
	ChannelId byte
	Uid       string
	Result    byte // type
}

type CodingResult struct {
	LineLength []byte
	Items      []CodingItem
}
type CodingItem struct {
	ChannelId     byte   // 通道
	DetonatorCode string // 管壳码
	Platform      byte   // 监管平台
	Permission    byte   // 许可
	Segment       []byte //段别
	Delay         []byte // 延期
	Result        byte   // type
}

type Sdk interface {
	OnProcessStart(h func())

	OnCheckConfirm(h func())
	CheckReply(cr CheckResult) (err error)

	Coding(h func())
	Recoding(h func())
	CodingReply(cr CodingResult) (err error)
	OnCodingResultConfirm(h func())

	OnProcessComplete(h func(result bool))
}

type sdk struct {
	session                     stream.Session
	processStartListener        func()
	checkConfirmListener        func()
	codingRequestListener       func()
	recodingRequestListener     func()
	codingResultConfirmListener func()
	completedListener           func(bool)
	ctx                         context.Context

	packet chan string
}

var (
	ErrCommunication = errors.New("communication error")
)

func New(ctx context.Context, portName string, baud int) (s Sdk, err error) {
	pp := NewPacketProcessor()
	port, err := stream.NewSerialSession(ctx, portName, baud,
		stream.WithReact(),
		stream.WithPacketProcessor(pp),
	)
	if err != nil {
		return
	}
	buf := bytes.Buffer{}
	buf.Grow(1024)
	handler := &sdk{
		session: port,
		ctx:     ctx,
		packet:  make(chan string),
	}
	pp.Listen(func(p []byte) {
		handler.packet <- string(p)
	})

	s = handler

	go handler.start()
	return
}
